0427. 建立四叉树【中等】
1. 📝 题目描述
给你一个 n * n 矩阵 grid,矩阵由若干 0 和 1 组成。请你用四叉树表示该矩阵 grid。
你需要返回能表示矩阵 grid 的 四叉树 的根结点。
四叉树数据结构中,每个内部节点只有四个子节点。此外,每个节点都有两个属性:
val:储存叶子结点所代表的区域的值。1 对应 True,0 对应 False。注意,当isLeaf为 False 时,你可以把 True 或者 False 赋值给节点,两种值都会被判题机制 接受。isLeaf: 当这个节点是一个叶子结点时为 True,如果它有 4 个子节点则为 False。
java
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
我们可以按以下步骤为二维区域构建四叉树:
- 如果当前网格的值相同(即,全为
0或者全为1),将isLeaf设为 True,将val设为网格相应的值,并将四个子节点都设为 Null 然后停止。 - 如果当前网格的值不同,将
isLeaf设为 False, 将val设为任意值,然后如下图所示,将当前网格划分为四个子网格。 - 使用适当的子网格递归每个子节点。

如果你想了解更多关于四叉树的内容,可以参考 百科。
四叉树格式:
你不需要阅读本节来解决这个问题。只有当你想了解输出格式时才会这样做。输出为使用层序遍历后四叉树的序列化形式,其中 null 表示路径终止符,其下面不存在节点。
它与二叉树的序列化非常相似。唯一的区别是节点以列表形式表示 [isLeaf, val]。
如果 isLeaf 或者 val 的值为 True,则表示它在列表 [isLeaf, val] 中的值为 1 ;如果 isLeaf 或者 val 的值为 False,则表示值为 0。
示例 1:

txt
输入:grid = [
[0, 1],
[1, 0]
]
输出:[
[0, 1],
[1, 0],
[1, 1],
[1, 1],
[1, 0]
]
解释:此示例的解释如下:
请注意,在下面四叉树的图示中,0 表示 false,1 表示 True。1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13

示例 2:

txt
输入:grid = [
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0]
]
输出:[
[0, 1],
[1, 1],
[0, 1],
[1, 1],
[1, 0],
null,
null,
null,
null,
[1, 0],
[1, 0],
[1, 1],
[1, 1]
]
解释:
网格中的所有值都不相同。我们将网格划分为四个子网格。
topLeft,bottomLeft 和 bottomRight 均具有相同的值。
topRight 具有不同的值,因此我们将其再分为 4 个子网格,这样每个子网格都具有相同的值。
解释如下图所示:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

提示:
n == grid.length == grid[i].lengthn == 2^x其中0 <= x <= 6
2. 🎯 s.1 - 递归
c
struct Node* build(int** grid, int r, int c, int size) {
if (size == 1) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->val = grid[r][c]; node->isLeaf = 1;
node->topLeft = node->topRight = node->bottomLeft = node->bottomRight = NULL;
return node;
}
int half = size / 2;
struct Node* tl = build(grid, r, c, half);
struct Node* tr = build(grid, r, c + half, half);
struct Node* bl = build(grid, r + half, c, half);
struct Node* br = build(grid, r + half, c + half, half);
if (tl->isLeaf && tr->isLeaf && bl->isLeaf && br->isLeaf &&
tl->val == tr->val && tr->val == bl->val && bl->val == br->val) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->val = tl->val; node->isLeaf = 1;
node->topLeft = node->topRight = node->bottomLeft = node->bottomRight = NULL;
free(tl); free(tr); free(bl); free(br);
return node;
}
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->val = 1; node->isLeaf = 0;
node->topLeft = tl; node->topRight = tr; node->bottomLeft = bl; node->bottomRight = br;
return node;
}
struct Node* construct(int** grid, int gridSize, int* gridColSize) {
return build(grid, 0, 0, gridSize);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
js
/**
* @param {number[][]} grid
* @return {_Node}
*/
var construct = function (grid) {
const build = (r, c, size) => {
if (size === 1) return new _Node(grid[r][c] === 1, true)
const half = size >> 1
const tl = build(r, c, half)
const tr = build(r, c + half, half)
const bl = build(r + half, c, half)
const br = build(r + half, c + half, half)
if (
tl.isLeaf &&
tr.isLeaf &&
bl.isLeaf &&
br.isLeaf &&
tl.val === tr.val &&
tr.val === bl.val &&
bl.val === br.val
) {
return new _Node(tl.val, true)
}
return new _Node(true, false, tl, tr, bl, br)
}
return build(0, 0, grid.length)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
py
class Solution:
def construct(self, grid: List[List[int]]) -> 'Node':
def build(r, c, size):
if size == 1:
return Node(grid[r][c] == 1, True)
half = size // 2
tl = build(r, c, half)
tr = build(r, c + half, half)
bl = build(r + half, c, half)
br = build(r + half, c + half, half)
if tl.isLeaf and tr.isLeaf and bl.isLeaf and br.isLeaf and tl.val == tr.val == bl.val == br.val:
return Node(tl.val, True)
return Node(True, False, tl, tr, bl, br)
return build(0, 0, len(grid))1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 时间复杂度:
,其中 是矩阵边长 - 空间复杂度:
,递归栈
算法思路:
- 递归分治:将矩阵四等分,分别构建子树
- 若四个子节点都是叶子且值相同,合并为一个叶子